#include "writetobuffer.h"

struct Vector4;
class MeshObject;

// =================================================================================================
// Thread function for rendering to a specific part of the buffer
// =================================================================================================
DWORD WINAPI WriteToBuffer(LPVOID param) {
    SimpleContainer* containers = (SimpleContainer*)param;
    Rect2D rect = containers->GetRect();
    MeshObject* mobject = containers->GetMesh();
    while(true) {

        if(*containers->GetTicket()) {
            *containers->GetTicket() = false;
            containers->GetViewport()->Render(*mobject, rect);
            *(containers->GetFinished()) = true;
        }

        if(!(*containers->GetRefresh())) {
            containers->GetViewport()->RefreshBuffers(rect);
            *containers->GetRefresh() = true;
            if(*containers->GetKill())
                return 0;
        }
    }

    return 0;
}

// ================================================================================================
// The main thread rendering algorithm
// ================================================================================================
void MainThread(SimpleContainer& container, Display& display) {
    MeshObject* mobject = container.GetMesh();
    Rect2D rect = container.GetRect();

    if(*container.GetTicket()) {
        *container.GetTicket() = false;
        container.GetViewport()->Render(*mobject, rect);
        *(container.GetFinished()) = true;
    }
}

// ================================================================================================
// The main thread for refreshing
// ================================================================================================
void MainThreadRefresh(SimpleContainer& container) {
    Rect2D rect = container.GetRect();

    container.GetViewport()->RefreshBuffers(rect);
    *container.GetRefresh() = true;
}
// ================================================================================================
// Reset the tickets
// ================================================================================================
void ResetTicket(SimpleContainer* containers, uint numcontainers) {
    for(uint i = 0; i < numcontainers; ++i) {
        *containers[i].GetTicket() = true;
        *(containers[i].GetFinished()) = false;
    }
}

// ================================================================================================
// Reset the refresh tickets
// ================================================================================================
void ResetRefresh(SimpleContainer* containers, uint numcontainers) {
    for(uint i = 0; i < numcontainers; ++i) 
        *containers[i].GetRefresh() = false;
}

// ================================================================================================
// Check to see if the threads are done
// ================================================================================================
bool CheckFinished(SimpleContainer* containers, uint numcontainers) {
    uint index = 0;
    for(uint i = 0; i < numcontainers; ++i) {
        if(*(containers[i].GetFinished()))
            ++index;
    }

    if(index == numcontainers)
        return true;

    return false;
}

// ================================================================================================
// Check to see if the threads are done reseting the buffer
// ================================================================================================
bool CheckRefreshFinished(SimpleContainer* containers, uint numcontainers) {
    uint index = 0;
    for(uint i = 0; i < numcontainers; ++i) {
        if(*containers[i].GetRefresh())
            ++index;
    }

    if(index == numcontainers)
        return true;

    return false;
}